package com.comm.utils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author mis_wu
 * @date 2022/6/20 14:39
 * @todo 日期格式处理
 */
public class DateUtil {
    private static final Logger log = LoggerFactory.getLogger(DateUtil.class);
    static Map<Integer, SimpleDateFormat> formatMap = new HashMap<>(16);
    private static final String DAY_SPLIT = "00:00:00";

    public DateUtil() {
    }

    private static SimpleDateFormat getFormat(String format) {
        SimpleDateFormat simpleDateFormat = (SimpleDateFormat)formatMap.get(format.hashCode());
        if (simpleDateFormat == null) {
            simpleDateFormat = new SimpleDateFormat(format);
            formatMap.put(format.hashCode(), simpleDateFormat);
        }

        return simpleDateFormat;
    }

    public static final Date getNowDate() {
        return new Date();
    }

    public static final Date getToday() {
        return getToday(getNowDate());
    }

    public static final Date getToday(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        calendar.set(14, 0);
        return calendar.getTime();
    }

    public static final Date getFirstDayOfMonth() {
        return getFirstDayOfMonth(getNowDate());
    }

    public static final Date getFirstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(5, 1);
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        calendar.set(14, 0);
        return calendar.getTime();
    }

    public static final int getWeek() {
        return getWeek(getNowDate());
    }

    public static final int getWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int week = calendar.get(7);
        return week == 1 ? 7 : week - 1;
    }

    public static final Date dateStrToDate(String dateStr) {
        try {
            Date date = getFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
            return date;
        } catch (ParseException var2) {
            log.error(var2.getMessage(), var2);
            return null;
        }
    }

    public static final Date dateStrTo(String dateStr, String format) {
        try {
            Date date = getFormat(format).parse(dateStr);
            return date;
        } catch (Exception var5) {
            log.error("日期参数：{},format：{},日期解析报错：{}", new Object[]{var5, dateStr, format});

            try {
                return getFormat(format).parse(getNowStr());
            } catch (ParseException var4) {
                return null;
            }
        }
    }

    public static final String getNowStr() {
        String result = getFormat("yyyy-MM-dd HH:mm:ss").format(getNowDate());
        return result;
    }

    public static final String getNowDayStr() {
        String result = getFormat("yyyy-MM-dd").format(getNowDate());
        return result;
    }

    public static String getDateStr(Date date) {
        String result = getFormat("yyyy-MM-dd HH:mm:ss").format(date);
        return result;
    }

    public static String getDateStr(Date date, String format) {
        String result = getFormat(format).format(date);
        return result;
    }

    public static boolean nowInToday() {
        return nowInToday((String)null);
    }

    public static boolean nowInToday(String split) {
        return dateInDay(getNowDate(), getDateStr(getNowDate(), "yyyy-MM-dd"), split);
    }

    public static boolean dateInToday(Date date) {
        return dateInToday(date, (String)null);
    }

    public static boolean dateInToday(Date date, String split) {
        return dateInDay(date, getDateStr(getNowDate(), "yyyy-MM-dd"), split);
    }

    public static boolean dateInDay(Date date, String day) {
        return dateInDay(date, day, (String)null);
    }

    public static boolean dateInDay(Date date, String day, String split) {
        split = StringUtils.isEmpty(split) ? "00:00:00" : split;
        day = day + " " + split;
        Date standardStart = dateStrToDate(day);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(standardStart);
        calendar.add(5, 1);
        Date standardEnd = calendar.getTime();
        return date.after(standardStart) && date.before(standardEnd);
    }

    public static int getHourOfDay(Date date, String split) {
        int minute = getMinuteOfDay(date, split);
        return minute / 60;
    }

    public static int getHourOfDay(Date date) {
        return getHourOfDay(date, (String)null);
    }

    public static int getMinuteOfDay(Date date, String split) {
        int second = getSecondOfDay(date, split);
        return second / 60;
    }

    public static int getMinuteOfDay(Date date) {
        return getMinuteOfDay(date, (String)null);
    }

    public static int getSecondOfDay(Date date) {
        return getSecondOfDay(date, (String)null);
    }

    public static int getSecondOfDay(Date date, String split) {
        split = StringUtils.isEmpty(split) ? "00:00:00" : split;
        Date standardTime = dateStrToDate(getDateStr(date, "yyyy-MM-dd") + " " + split);
        long standardSecond = standardTime.getTime() / 1000L;
        long dateSecond = date.getTime() / 1000L;
        return (int)(dateSecond - standardSecond);
    }

    public static final Date dateAddSub(Date date, int unit, int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(unit, num);
        return calendar.getTime();
    }

    public static final Date dateAddSubDay(Date date, int num) {
        return dateAddSub(date, 5, num);
    }

    public static boolean checkBetween(Date base, Date start, Date end) {
        Date date = getNowDate();
        return date.before(start) && date.after(end);
    }

    public static boolean checkBetween(Date start, Date end) {
        return checkBetween(getNowDate(), start, end);
    }
}
